// stack.hxx


#ifndef _BLOGS_STACK
#define _BLOGS_STACK


#include "node.hxx"


namespace blogs
{


template <class _T>
class Stack
{

  private:

    int
    __N__;


    Node<_T> *
    __first__;


  public:

    Stack()
        : __N__(0), __first__(nullptr)
    {
    }


    Stack(Stack const& other)
    {
        __N__ = 0;
        __first__ = nullptr;
        Node<_T> * po = other.__first__;
        Node<_T> * prev;
        Node<_T> * n = nullptr;
        while (po) {
            prev = n;
            n = new Node<_T>;
            n->item = po->item;
            if (prev)
                prev->next = n;
            else
                __first__ = n;
            po = po->next;
            ++__N__;
        }
    }


    ~Stack()
    {
        Node<_T> * prev;
        while (__first__) {
            prev = __first__;
            __first__ = __first__->next;
            --__N__;
            delete prev;
        }
    }


    bool
    is_empty()
    {
        return __first__ == nullptr;
    }


    int
    size()
    {
        return __N__;
    }


    void
    push(_T item)
    {
        Node<_T> * prev = __first__;
        __first__ = new Node<_T>;
        __first__->item = item;
        __first__->next = prev;
        ++__N__;
    }


    _T
    pop()
    {
        Node<_T> * prev = __first__;
        _T item = __first__->item;
        __first__ = __first__->next;
        --__N__;
        delete prev;
        return item;
    }


    _T
    peek()
    {
        return __first__->item;
    }

};


} // end of namespace blogs


#endif

